'''
Created on 2013-7-2

@author: LJ
'''
from xml.etree import ElementTree as ET

def stripjin(st):
    return st[1:]

class ogtxml:
    files="ogt.owl"
    tree = ET.parse(files)
    ns = {'owl':'http://www.w3.org/2002/07/owl#'}
    base = "{%(owl)s}"%ns
    
    annotations = []
    knowledges = []
    resources = []
    annotations1 = []
    knowledges1 = []
    resources1 = []
    annotations2 = []
    knowledges2 = []
    resources2 = []
    
    hasannotations = []
    hasknowledges = []
    hasresources = []
    hasannotations2 = []
    hasknowledges2 = []
    hasresources2 = []
    
    objectDomainPairs = None
    objectRangePairs = None
    equivalentPairs = None
    
    annotationForms = {}
    resourceForms = {}
    xsdForms = {'xsd:string':'text', 'xsd:dateTime':'datetime', 'xsd:language':'text', 'xsd:normalizedString':'text'}
    form2sql = {'textarea':' TEXT ', 'text':' varchar(50) ', 'datetime':' datetime DEFAULT NULL ', 'int':' int(11) ',
                'option':'varchar(50)', 'file':'varchar(50)'}
    resourceSpe = ['creator', 'date', 'ID', 'localPath'] #insert notice ID
    
    
    @staticmethod
    def getClasses():
        subClassPairs = ogtxml.tree.findall(ogtxml.base+"SubClassOf")
        Cannotation = "Annotation"
        Cknowledge = "Knowledge"
        Cresource = "Resource"
        restPairs = []
        for i in subClassPairs:
            st = i.getchildren()[1].get('IRI', 'default')
            st = stripjin(st)
            if st == Cannotation:
                ogtxml.annotations.append(stripjin(i.getchildren()[0].get('IRI','default')))
            elif st == Cknowledge:
                ogtxml.knowledges.append(stripjin(i.getchildren()[0].get('IRI','default')))
            elif st == Cresource:
                ogtxml.resources.append(stripjin(i.getchildren()[0].get('IRI','default')))
            else:
                restPairs.append(i)
        ogtxml.annotations1 = [i for i in ogtxml.annotations]
        ogtxml.knowledges1 = [i for i in ogtxml.knowledges]
        ogtxml.resources1 =  [i for i in ogtxml.resources]
        for i in restPairs:
            st = i.getchildren()[1].get('IRI', 'default')
            st = stripjin(st)
            if st in ogtxml.annotations:
                ogtxml.annotations.append(stripjin(i.getchildren()[0].get('IRI','default')))
                if st not in ogtxml.annotations2:
                    ogtxml.annotations2.append(st)
            elif st in ogtxml.knowledges:
                ogtxml.knowledges.append(stripjin(i.getchildren()[0].get('IRI','default')))
                if st not in ogtxml.knowledges2:
                    ogtxml.knowledges2.append(st)
            elif st in ogtxml.resources:
                ogtxml.resources.append(stripjin(i.getchildren()[0].get('IRI','default')))
                if st not in ogtxml.resources2:
                    ogtxml.resources2.append(st)
        ogtxml.annotations2 = [i for i in ogtxml.annotations if i not in ogtxml.annotations2 ]
        ogtxml.knowledges2 = [i for i in ogtxml.knowledges if i not in ogtxml.knowledges2 ]
        ogtxml.resources2 =  [i for i in ogtxml.resources if i not in ogtxml.resources2 ]
        ogtxml.annotations.append(Cannotation)
        ogtxml.knowledges.append(Cknowledge)
        ogtxml.resources.append(Cresource)
        if __name__ == "__main__":
            print "-----classes-------"
            print ogtxml.annotations
            print ogtxml.knowledges
            print ogtxml.resources
            print ogtxml.annotations2
            print ogtxml.knowledges2
            print ogtxml.resources2
    @staticmethod
    def parentClasses(stknowres):
        Cknowledge = "Knowledge"
        Cresource = "Resource"
        if stknowres in ogtxml.knowledges:
            if stknowres == Cknowledge:
                return []
            elif stknowres in ogtxml.knowledges1:
                return [Cknowledge]
            else:
                subClassPairs = ogtxml.tree.findall(ogtxml.base+"SubClassOf")
                for i in subClassPairs:
                    if stripjin(i.getchildren()[0].get('IRI', 'default')) == stknowres:
                        return [Cknowledge, stripjin(i.getchildren()[1].get('IRI', 'default'))]
        else:
            if stknowres == Cresource:
                return []
            elif stknowres in ogtxml.resources1:
                return [Cresource]
            else:
                subClassPairs = ogtxml.tree.findall(ogtxml.base+"SubClassOf")
                for i in subClassPairs:
                    if stripjin(i.getchildren()[0].get('IRI', 'default')) == stknowres:
                        return [Cresource, stripjin(i.getchildren()[1].get('IRI', 'default'))]
    @staticmethod
    def getProperties():
        subObjectProPairs = ogtxml.tree.findall(ogtxml.base+"SubObjectPropertyOf")
        restPairs = []
        Chasannotation = "hasAnnotation"
        Chasknowledge = "hasKnowledge"
        Chasresource = "hasResource"
        for i in subObjectProPairs:
            st = i.getchildren()[1].get('IRI', 'default')
            st = stripjin(st)
            if st == Chasannotation:
                ogtxml.hasannotations.append(stripjin(i.getchildren()[0].get('IRI','default')))
            elif st == Chasknowledge:
                ogtxml.hasknowledges.append(stripjin(i.getchildren()[0].get('IRI','default')))
            elif st == Chasresource:
                ogtxml.hasresources.append(stripjin(i.getchildren()[0].get('IRI','default')))
            else:
                restPairs.append(i)
        for i in restPairs:
            st = i.getchildren()[1].get('IRI', 'default')
            st = stripjin(st)
            if st in ogtxml.hasannotations:
                ogtxml.hasannotations.append(stripjin(i.getchildren()[0].get('IRI','default')))
                if st not in ogtxml.hasannotations2:
                    ogtxml.hasannotations2.append(st)
            elif st in ogtxml.hasknowledges:
                ogtxml.hasknowledges.append(stripjin(i.getchildren()[0].get('IRI','default')))
                if st not in ogtxml.hasknowledges2:
                    ogtxml.hasknowledges2.append(st)
            elif st in ogtxml.hasresources:
                ogtxml.hasresources.append(stripjin(i.getchildren()[0].get('IRI','default')))
                if st not in ogtxml.hasresources2:
                    ogtxml.hasresources2.append(st)
        ogtxml.hasannotations2 = [i for i in ogtxml.hasannotations if i not in ogtxml.hasannotations2 ]
        ogtxml.hasknowledges2 = [i for i in ogtxml.hasknowledges if i not in ogtxml.hasknowledges2 ]
        ogtxml.hasresources2 =  [i for i in ogtxml.hasresources if i not in ogtxml.hasresources2 ]
        ogtxml.hasannotations.append(Chasannotation)
        ogtxml.hasknowledges.append(Chasknowledge)
        ogtxml.hasresources.append(Chasresource)
        if __name__ == "__main__":
            print "-----properties-------"
            print ogtxml.hasannotations
            print ogtxml.hasknowledges
            print ogtxml.hasresources
            print ogtxml.hasannotations2
            print ogtxml.hasknowledges2
            print ogtxml.hasresources2
    @staticmethod
    def objDomains(node):
        li = []
        if node.find(ogtxml.base+"ObjectUnionOf"):
            for j in node.getchildren()[1].getchildren():
                s = j.get('IRI', 'default')
                s = stripjin(s)
                li.append(s)
        else:
            li.append(stripjin(node.getchildren()[1].get('IRI','default')))
        return li
    @staticmethod
    def objRangeClass(hasst):
        for i in ogtxml.objectRangePairs:
            s = i.getchildren()[0].get('IRI', 'default')
            s = stripjin(s)
            if s == hasst:
                return stripjin(i.getchildren()[1].get('IRI', 'default'))
    @staticmethod
    def isAnyInclude(li1, li2):
        for i in li1:
            if i in li2:
                return True
        return False
    @staticmethod
    def annotationsProperties(stknowres):
        li = []
        pli = ogtxml.parentClasses(stknowres)
        for i in ogtxml.objectDomainPairs:
            st = i.getchildren()[0].get('IRI', 'default')
            st = stripjin(st)
            if st in ogtxml.hasannotations:
                if stknowres in ogtxml.objDomains(i) or ogtxml.isAnyInclude(pli,ogtxml.objDomains(i)):
                    li.append( [st, ogtxml.objRangeClass(st)] )
        return li
    @staticmethod
    def getAnnotationForms(stknowres):
        di = {}
        for i in ogtxml.annotationsProperties(stknowres):
            di[i[1]] = ogtxml.annotationForms.get(i[1], 'text')
        return di
    @staticmethod
    def resourcesProperties(stknow):
        li = []
        pli = ogtxml.parentClasses(stknow)
        for i in ogtxml.objectDomainPairs:
            st = i.getchildren()[0].get('IRI', 'default')
            st = stripjin(st)
            if st in ogtxml.hasresources and (stknow in ogtxml.objDomains(i) or ogtxml.isAnyInclude(pli, ogtxml.objDomains(i))):
                li.append([st, ogtxml.objRangeClass(st)])
        return li
    @staticmethod
    def resourcesProList(stknow):
        li = []
        for i in ogtxml.resourcesProperties(stknow):
            li.append(i[1])
        return li
    @staticmethod
    def getResourceForms(stknow):
        di ={}
        for i in ogtxml.resourcesProperties(stknow):
            di[i[1]] = ogtxml.resourceForm(i[1])
        return di
    @staticmethod
    def resourceForm(stres):
        di = ogtxml.getAnnotationForms(stres)
        for i in ogtxml.localAnnotationProperties(stres):
            if i[0] not in ogtxml.resourceSpe:
                di[i[0]] = ogtxml.xsdForms[i[1]]
        di["resource"] = ogtxml.resourceForms.get(stres, "text")
        return di
    @staticmethod
    def res2props(stres):
        di = ogtxml.getAnnotationForms(stres)
        for i in ogtxml.localAnnotationProperties(stres):
            if i[0] == 'ID':
                pass
            elif i[0] == 'creator':
                di[i[0]] = 'int'
            else:
                di[i[0]] = ogtxml.xsdForms[i[1]]
        di["resource"] = ogtxml.resourceForms.get(stres, "text")
        return di
    @staticmethod
    def knowledgesProperties(stknow):
        li = []
        pli = ogtxml.parentClasses(stknow)
        for i in ogtxml.objectDomainPairs:
            st = i.getchildren()[0].get('IRI', 'default')
            st = stripjin(st)
            if st in ogtxml.hasknowledges and (stknow in ogtxml.objDomains(i) or ogtxml.isAnyInclude(pli, ogtxml.objDomains(i))):
                li.append([st, ogtxml.objRangeClass(st)])
        return li
    
    @staticmethod
    def localAnnotationProperties(stknowres):
        annotationDomainPairs = ogtxml.tree.findall(ogtxml.base+"AnnotationPropertyDomain")
        annotationRangePairs = ogtxml.tree.findall(ogtxml.base+"AnnotationPropertyRange")
        li = []
        pli = ogtxml.parentClasses(stknowres)
        pli.append(stknowres)
        for i in annotationDomainPairs:
            st = stripjin( i.getchildren()[1].text )
            if st in pli:
                s = stripjin( i.getchildren()[0].get('IRI', '#default') )
                if s == "default":
                    s = i.getchildren()[0].get('abbreviatedIRI', 'default')
                if s != "default":
                    for j in annotationRangePairs:
                        if stripjin(j.getchildren()[0].get('IRI', '#default')) == s or \
                        j.getchildren()[0].get('abbreviatedIRI', 'default') == s:
                            li.append( [s[s.find(":")+1:], j.getchildren()[1].text] )
        return li
    @staticmethod
    def label2form():
        labelPairs = ogtxml.tree.findall(ogtxml.base+"AnnotationAssertion")
        for i in labelPairs:
            if i.getchildren()[0].get('abbreviatedIRI', 'default') == 'rdfs:label':
                s = stripjin(i.getchildren()[1].text)
                if s in ogtxml.annotations:
                    ogtxml.annotationForms[s] = i.getchildren()[2].text
                elif s in ogtxml.resources:
                    ogtxml.resourceForms[s] = i.getchildren()[2].text
        if __name__ == "__main__":
            print "-----label2form-------"
            print ogtxml.annotationForms
            print ogtxml.resourceForms
    @staticmethod
    def equivalentOptions(stequi):
        li = []
        for i in ogtxml.equivalentPairs:
            s = stripjin(i.getchildren()[0].get('IRI', 'default'))
            if s == stequi:
                for j in i.getchildren()[1].getchildren():
                    li.append(stripjin(j.get('IRI', 'default')))
        return li
    @staticmethod
    def generateSql():
        sqlfile = "ogtxml.sql"
        fd = file(sqlfile, 'w')
        fd.write("\n")
        ogtxml.others2sql(fd)
        fd.write("\n"*10)
        ogtxml.allKnowledge2sql(fd)
        fd.write("\n"*10)
        ogtxml.allResource2sql(fd)
        #fd.write("\n"*10)
        fd.close()
    @staticmethod
    def allKnowledge2sql(fd):
        for i in ogtxml.knowledges2:
            fd.write( ogtxml.knowledge2sql(i) )
            fd.write("\n"*2)
    @staticmethod
    def allResource2sql(fd):
        for i in ogtxml.resources2:
            fd.write( ogtxml.resource2sql(i) )
            fd.write("\n"*2)
    @staticmethod
    def others2sql(fd):
        sttable = "knows"
        sql = "DROP TABLE IF EXISTS "+sttable+" ;\n"
        sql += "CREATE TABLE IF NOT EXISTS "+sttable+" ( "
        sql += " id int(11) NOT NULL AUTO_INCREMENT "
        knowForms = {'knowledge':'text','name':'text','version':'int'}
        for i,j in knowForms.items():
            st = ", "+ i + " "+ ogtxml.form2sql.get(j," varchar(50) ")
            sql += st
        sql += " , PRIMARY KEY (id)"
        sql += ");"
        fd.write(sql)
        fd.write("\n"*3)
        
        sttable = "know2res"
        sql = "DROP TABLE IF EXISTS "+sttable+" ;\n"
        sql += "CREATE TABLE IF NOT EXISTS "+sttable+" ( "
        sql += " id int(11) NOT NULL AUTO_INCREMENT "
        knowresForms = {'knowledge':'text', 'kid':'int','resource':'text','rid':'int'}
        for i,j in knowresForms.items():
            st = ", "+ i + " "+ ogtxml.form2sql.get(j," varchar(50) ")
            sql += st
        sql += " , PRIMARY KEY (id)"
        sql += ");"
        fd.write(sql)
        fd.write("\n"*3)
        
        sttable = "know2know"
        sql = "DROP TABLE IF EXISTS "+sttable+" ;\n"
        sql += "CREATE TABLE IF NOT EXISTS "+sttable+" ( "
        sql += " id int(11) NOT NULL AUTO_INCREMENT "
        knowknowForms = {'know1':'text', 'id1':'int', 'hasknow':'text','know2':'text','id2':'int'}
        for i,j in knowknowForms.items():
            st = ", "+ i + " "+ ogtxml.form2sql.get(j," varchar(50) ")
            sql += st
        sql += " , PRIMARY KEY (id)"
        sql += ");"
        fd.write(sql)
        fd.write("\n"*3)
        
        sttable = "res2point"
        sql = "DROP TABLE IF EXISTS "+sttable+" ;\n"
        sql += "CREATE TABLE IF NOT EXISTS "+sttable+" ( "
        sql += " id int(11) NOT NULL AUTO_INCREMENT "
        resPointForms = {'resource':'text', 'rid':'int', 'creator':'int', 'date':'datetime','value':'int', 'comment':'textarea'}
        for i,j in resPointForms.items():
            st = ", "+ i + " "+ ogtxml.form2sql.get(j," varchar(50) ")
            sql += st
        sql += " , PRIMARY KEY (id)"
        sql += ");"
        fd.write(sql)
        fd.write("\n"*3)
        
        sttable = "knowsame"
        sql = "DROP TABLE IF EXISTS "+sttable+" ;\n"
        sql += "CREATE TABLE IF NOT EXISTS "+sttable+" ( "
        sql += " id int(11) NOT NULL AUTO_INCREMENT "
        knowsameForms = {'name1':'text', 'name2':'text', 'knowledge':'text'}
        for i,j in knowsameForms.items():
            st = ", "+ i + " "+ ogtxml.form2sql.get(j," varchar(50) ")
            sql += st
        sql += " , PRIMARY KEY (id)"
        sql += ");"
        fd.write(sql)
        fd.write("\n"*3)
        
        sttable = "users"
        sql = "DROP TABLE IF EXISTS "+sttable+" ;\n"
        sql += "CREATE TABLE IF NOT EXISTS "+sttable+" ( "
        sql += " id int(11) NOT NULL AUTO_INCREMENT "
        knowsameForms = {'fullname':' varchar(30) ', 'email':' varchar(40) ', 'pass':' varchar(40) ', 'register_time':' datetime DEFAULT NULL ',
                         'authority': ' int(6) ', 'location': ' varchar(30) ', 'homepage':' varchar(50) ', 'birth': ' date DEFAULT NULL '}
        for i,j in knowsameForms.items():
            st = ", "+ i + " "+ j
            sql += st
        sql += " , PRIMARY KEY (id)"
        sql += ");"
        fd.write(sql)
        fd.write("\n"*3)
        
    @staticmethod
    def knowledge2sql(stknow):
        sql = "DROP TABLE IF EXISTS "+stknow+" ;\n"
        sql += "CREATE TABLE IF NOT EXISTS "+stknow+" ( "
        sql += " id int(11) NOT NULL AUTO_INCREMENT "
        sql += ", knowid int(11) NOT NULL "
        for i,j in ogtxml.getAnnotationForms(stknow).items():
            st = ", "+ i + " " + ogtxml.form2sql.get(j," varchar(50) ")
            sql += st
        for i,j in {'creator':'int', 'date':'datetime'}.items():
            st = ", "+ i + " " + ogtxml.form2sql.get(j," varchar(50) ")
            sql += st
        sql += " , PRIMARY KEY (id)"
        sql += ");"
        return sql
    @staticmethod
    def resource2sql(stres):
        sql = "DROP TABLE IF EXISTS "+stres+" ;\n"
        sql += "CREATE TABLE IF NOT EXISTS "+stres+" ( "
        sql += " id int(11) NOT NULL AUTO_INCREMENT "
        for i,j in ogtxml.res2props(stres).items():
            if i == 'localPath':
                sql += ", "+ i + " varchar(50) "
            else:
                st = ", "+ i + " "+ ogtxml.form2sql.get(j," varchar(50) ")
                sql += st
        sql += " , PRIMARY KEY (id)"
        sql += ");"
        return sql
    
            
        



#static class initial
ogtxml.getClasses()
ogtxml.getProperties()
ogtxml.objectDomainPairs = ogtxml.tree.findall(ogtxml.base+"ObjectPropertyDomain")
ogtxml.objectRangePairs = ogtxml.tree.findall(ogtxml.base+"ObjectPropertyRange")
ogtxml.label2form()
ogtxml.equivalentPairs = ogtxml.tree.findall(ogtxml.base+"EquivalentClasses")




#test
if __name__ == "__main__":
    stknowledge = "Problem"
    print "-------test: %s ---------"%stknowledge
    print "--annotationsProperties:--"
    print ogtxml.annotationsProperties(stknowledge)
    print "--resourcesProperties:--"
    print ogtxml.resourcesProperties("Example")
    print "--resourcesProList:--"
    print ogtxml.resourcesProList("Example")
    print "--getAnnotationForms:--"
    print ogtxml.getAnnotationForms(stknowledge)
    print "--getResourceForms:--"
    print ogtxml.getResourceForms(stknowledge)
    print "--knowledge2sql:--"
    print ogtxml.knowledge2sql(stknowledge)
    print "--resource2sql:--"
    print ogtxml.resource2sql("Image")
    print "--generateSql:--"
    print ogtxml.generateSql()
    
    
    print "--knowledgesProperties:Concept--"
    print ogtxml.knowledgesProperties("Algorithm")
    print "--localAnnotationProperties:Resource--"
    print ogtxml.localAnnotationProperties("Image") #"Knowledge"
    print "--equivalentOptions:VideoFormat--"
    print ogtxml.equivalentOptions('VideoFormat')
    print "--resourceForm:Image--"
    print ogtxml.resourceForm('Image')
    print "--res2props:Image--"
    print ogtxml.res2props('Image')
    print "--parentClasses:Concept--"
    print ogtxml.parentClasses("FormalizedText")
    
    
    



